package com.amithkoujalgi.framework.rest.util;


import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;

import javax.ws.rs.client.Client;
import javax.ws.rs.client.ClientBuilder;
import javax.ws.rs.client.Entity;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;

import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.NameValuePair;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;
import org.glassfish.jersey.jackson.JacksonFeature;

@SuppressWarnings("deprecation")
public class HTTPUtil
{

	@SuppressWarnings("resource")
	public <T> Object get( String endPointURL, Class<T> responseMapperClass ) throws Exception
	{
		HttpClient client = new DefaultHttpClient();
		HttpGet request = new HttpGet( endPointURL );
		HttpResponse response = client.execute( request );
		// Get the response
		BufferedReader rd = new BufferedReader( new InputStreamReader( response.getEntity().getContent() ) );
		String line = "", read = "";
		while( (line = rd.readLine()) != null )
		{
			read = read + "\n " + line;
		}
		return JSONUtil.parse( read, responseMapperClass );
	}

	@SuppressWarnings("resource")
	public <T> Object post( String endPointURL, Object param, Class<T> responseMapperClass ) throws Exception
	{
		HttpClient client = new DefaultHttpClient();
		HttpPost post = new HttpPost( endPointURL );
		List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>( 1 );
		nameValuePairs.add( new BasicNameValuePair( "data", JSONUtil.toJSON( param ) ) );
		post.setEntity( new UrlEncodedFormEntity( nameValuePairs ) );
		HttpResponse response = client.execute( post );
		BufferedReader rd = new BufferedReader( new InputStreamReader( response.getEntity().getContent() ) );
		String line = "", read = "";
		while( (line = rd.readLine()) != null )
		{
			read = read + "\n " + line;
		}
		return JSONUtil.parse( read, responseMapperClass );
	}

	@SuppressWarnings("resource")
	public String get( String endPointURL ) throws Exception
	{
		HttpClient client = new DefaultHttpClient();
		HttpGet request = new HttpGet( endPointURL );
		HttpResponse response = client.execute( request );
		// Get the response
		BufferedReader rd = new BufferedReader( new InputStreamReader( response.getEntity().getContent() ) );
		String line = "", read = "";
		while( (line = rd.readLine()) != null )
		{
			read = read + "\n " + line;
		}
		return read;
	}

	@SuppressWarnings("resource")
	public String post( String endPointURL, Object param ) throws Exception
	{
		HttpClient client = new DefaultHttpClient();
		HttpPost post = new HttpPost( endPointURL );
		List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>( 1 );
		nameValuePairs.add( new BasicNameValuePair( "data", JSONUtil.toJSON( param ) ) );
		post.setEntity( new UrlEncodedFormEntity( nameValuePairs ) );
		HttpResponse response = client.execute( post );
		BufferedReader rd = new BufferedReader( new InputStreamReader( response.getEntity().getContent() ) );
		String line = "", read = "";
		while( (line = rd.readLine()) != null )
		{
			read = read + "\n " + line;
		}
		return read;
	}

	@SuppressWarnings("resource")
	public HttpResponse getWithRawResponse( String endPointURL ) throws Exception
	{
		HttpClient client = new DefaultHttpClient();
		HttpGet request = new HttpGet( endPointURL );
		HttpResponse response = client.execute( request );
		return response;
	}

	@SuppressWarnings("resource")
	public HttpResponse postWithRawResponse( String endPointURL, Object param ) throws Exception
	{
		HttpClient client = new DefaultHttpClient();
		HttpPost post = new HttpPost( endPointURL );
		List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>( 1 );
		nameValuePairs.add( new BasicNameValuePair( "data", JSONUtil.toJSON( param ) ) );
		post.setEntity( new UrlEncodedFormEntity( nameValuePairs ) );
		HttpResponse response = client.execute( post );
		return response;
	}

	public String parseHTTPResponse( HttpResponse response ) throws IllegalStateException, IOException
	{
		BufferedReader rd = new BufferedReader( new InputStreamReader( response.getEntity().getContent() ) );
		String line = "", read = "";
		while( (line = rd.readLine()) != null )
		{
			read = read + "\n " + line;
		}
		return read;
	}

	public <T> Object restPost( String url, Class<T> responseMapperClass, Object entity ) throws Exception
	{
		try
		{
			Client client = ClientBuilder.newClient().register( JacksonFeature.class );
			Response r = client.target( url ).request().post( Entity.entity( entity, MediaType.APPLICATION_JSON ) );
			if( r.getStatus() == HttpStatus.SC_OK || r.getStatus() == HttpStatus.SC_NO_CONTENT )
			{
				return r.readEntity( responseMapperClass );
			}
			else
			{
				com.amithkoujalgi.framework.rest.core.WebAppError ud = r
						.readEntity( com.amithkoujalgi.framework.rest.core.WebAppError.class );
				System.out.println( ud.getExceptionStackTrace() );
				System.out.println( ud.getStatusCode() );
				System.out.println( ud.getMessage() );
				throw new Exception( ud.getExceptionStackTrace() + "\n" + ud.getStatusCode() );
			}
		}
		catch( Exception e )
		{
			throw e;
		}
	}

	public <T> Object restGet( String url, Class<T> responseMapperClass ) throws Exception
	{
		// logger.info("REST GET: " + url);
		try
		{
			Client client = ClientBuilder.newClient().register( JacksonFeature.class );
			Response r = client.target( url ).request().get();
			if( r.getStatus() == HttpStatus.SC_OK || r.getStatus() == HttpStatus.SC_NO_CONTENT )
			{
				return r.readEntity( responseMapperClass );
			}
			else
			{
				/*
				 * logger.error("REST GET: " + url + " - [Response Status: " +
				 * r.getStatus() + " - " + r.getStatusInfo() + "]");
				 */
				com.amithkoujalgi.framework.rest.core.WebAppError ud = r
						.readEntity( com.amithkoujalgi.framework.rest.core.WebAppError.class );
				System.out.println( ud.getExceptionStackTrace() );
				System.out.println( ud.getStatusCode() );
				System.out.println( ud.getMessage() );
				throw new Exception( ud.getExceptionStackTrace() + "\n" + ud.getStatusCode() );
			}
		}
		catch( Exception e )
		{
			throw e;
		}
	}
}